//
//  MyViewController.m
//  RuntimeDemo
//
//  Created by LMM on 7/21/15.
//  Copyright (c) 2015 LMM. All rights reserved.
//

#import "MyViewController.h"
//#import <objc/objc-runtime.h>
#import <objc/runtime.h>
#import <objc/objc.h>
#include <objc/objc-api.h>
#import <objc/message.h>
#import "TestModel.h"
//#import "APService.h"
#import "MobClick.h"
#import "RootScene.h"

#define CLASSNAME NSStringFromClass([self class])

@interface MyViewController ()
@property (weak, nonatomic) IBOutlet UIButton *testBtn;
@property (nonatomic, strong)TestModel *testModel;
- (void)buttonTarget;
+(void)test;
@end
IMP orginIMP;
// 监控某个方法执行的次数
NSString *MyUppercaseString(id SELF, SEL _cmd)
{
    static NSInteger number = 0;
    NSString *str = orginIMP(SELF, _cmd);
    number++;
    NSLog(@"%@这个方法执行的第%d遍", NSStringFromSelector(_cmd), (int)number);
    [MobClick event:@"changeColor" attributes:@{@"color":@"clearColor"} counter:(int)number];

    return str;
}
@implementation MyViewController

+(void)test
{
    NSLog(@"test");
}
- (void)testReplaceMethod
{
    Class strcls = [NSString class];
    SEL oriUppercaseString = @selector(uppercaseString);
    orginIMP = [NSString instanceMethodForSelector:@selector(uppercaseString)];
    // 给uppercaseString这个方法添加添加一个功能
    class_replaceMethod(strcls, oriUppercaseString, (IMP)MyUppercaseString, NULL);
}
- (void)noti:(NSNotification *)noti
{
    if ([noti.object isEqualToString:@"123"]) {
        [self performSegueWithIdentifier:@"hahahaha" sender:nil];
//        RootScene *rootS = [[RootScene alloc] init];
//        [self presentViewController:rootS animated:YES completion:^{
//            
//        }];
    }
}
- (void)viewDidLoad {
    [super viewDidLoad];
    // Do any additional setup after loading the view.
    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(noti:) name:@"tuisong" object:nil];
    
    
    //给现有方法添加功能
    self.testModel = [TestModel new];
    objc_msgSend(self, @selector(testReplaceMethod));     // 相当于 [self testReplaceMethod];
    // 给返回void的函数添加返回类型
    objc_msgSend(self, @selector(addIndicatiorFunction));
    // 这个button方法实现没有写
    [self.testBtn addTarget:self action:@selector(buttonTarget) forControlEvents:UIControlEventTouchUpInside];
    // 让self.testModel 调用lowercaseString
//    [self.testModel performSelector:@selector(uppercaseString)];
    [MyViewController test];
    
    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(changeColor:) name:@"notification" object:nil];
    // UM
    [MobClick beginLogPageView:CLASSNAME];
}
- (void)viewWillDisappear:(BOOL)animated
{
    [[NSNotificationCenter defaultCenter] removeObserver:self name:@"notification" object:nil];
    [MobClick endLogPageView:CLASSNAME];
}
- (void)changeColor:(NSNotification *)noti
{
    NSLog(@"%@", noti);
    self.testBtn.titleLabel.textColor = [UIColor blackColor];
}
- (void)addIndicatiorFunction
{
//    CGRect (*getRectFn)(id receiver, SEL operation); // 定义一个返回值为rect的函数
//    getRectFn = (CGRect (*)(id, SEL))objc_msgSend_stret; // objc_msgSend_stret这个方法是不能返回值的 让新定义的函数指向这个函数
//    CGRect frame = getRectFn(self.testBtn, @selector(frame)); // 得到button的frame
//    NSLog(@"button's frame:%.2f, %.2f, %.2f, %.2f", frame.origin.x, frame.origin.y, frame.size.width, frame.size.height);
    
}
// 点击按钮事件
- (void)anthorButtonTarget
{
    self.testBtn.backgroundColor = [UIColor colorWithRed:arc4random() % 255 / 255.0  green:arc4random() % 255 / 255.0 blue:arc4random() % 255 / 255.0 alpha:1];
    // 让uppercaseString执行10次
    NSString *string = [NSString string];
        [string uppercaseString];
    // UM
    [MobClick event:@"click"];
}
void dynamicMethodIMP(id self, SEL _cmd)
{
    NSLog(@"没有 %@ 这个方法,给您转到另外一个方法了", NSStringFromSelector(_cmd));
    [self anthorButtonTarget];
}
// 如果某个没有实现的方法被调用，次方法将被触发
+ (BOOL)resolveInstanceMethod:(SEL)sel
{
    if (sel == @selector(buttonTarget)) {
        class_replaceMethod([self class], sel, (IMP)dynamicMethodIMP, "v@:");
        
        
        
        return YES;
    }
    return [super resolveInstanceMethod:sel];
}
+(BOOL)resolveClassMethod:(SEL)sel
{
    
    return [super resolveClassMethod:sel];
}
- (void)didReceiveMemoryWarning {
    [super didReceiveMemoryWarning];
    // Dispose of any resources that can be recreated.
}

- (void)someObjcFunction
{
//    unsigned int outCount = 0;
    const char *className = class_getName([_testModel class]); // 获取对象的类名
    NSLog(@"testModel's class:%s", className);
    Class superClass = class_getSuperclass([_testModel class]); // 获取父类的名字
    NSLog(@"testModel's superClass:%@", superClass);
//    NSLog(@"%d", objc_getClassList(NULL, 0));
    NSLog(@"%zu", class_getInstanceSize([_testModel class]));
    
}

/*
#pragma mark - Navigation

// In a storyboard-based application, you will often want to do a little preparation before navigation
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
    // Get the new view controller using [segue destinationViewController].
    // Pass the selected object to the new view controller.
}
*/

@end
